<?php

namespace app\api\controller\Online;

use app\api\controller\Common;
use app\api\Logic\Online\OnlineVideoLogic;
use app\api\Logic\Online\OnlineVideoOrderLogic;
use app\api\Logic\Pay\PayLogic;
use app\api\model\OnlineVideoOrderModel;
use app\api\model\OnlineVideoSublevelLogModel;
use app\api\model\OnlineVideoSublevelModel;
use think\Db;
use think\Exception;

/**
 * 在线课程订单接口
 */
class VideoOrder extends Common
{
    protected $noNeedLogin = ['*'];

    protected $onlineVideoLogic;
    protected $onlineVideoOrderLogic;
    protected $payLogic;

    public function _initialize()
    {
        parent::_initialize();
        $this->onlineVideoLogic = new OnlineVideoLogic();
        $this->onlineVideoOrderLogic = new OnlineVideoOrderLogic();
        $this->payLogic = new PayLogic();
    }

    /**
     * 支付方式
     * @return array[]
     */
    public function payTypeMap(){
        return [
            1 => ['type' => 1, 'name' => '微信支付'],
            2 => ['type' => 2, 'name' => '支付宝'],
            3 => ['type' => 3, 'name' => '银联支付']
        ];
    }

    /**
     * 学习状态
     * @return array[]
     */
    public function studyStatusMap(){
        return [
            0 => ['type' => 0, 'name' => '未学习'],
            1 => ['type' => 1, 'name' => '学习中'],
            2 => ['type' => 2, 'name' => '已完课']
        ];
    }

    /**
     * 供前端调用，返回支付方式
     */
    public function payTypeAry(){
        $list = array_values($this->payTypeMap());
        if (!empty($list)) {
            $this->success('查询成功', $list);
        }
        $this->error('暂无数据');
    }

    /**
     * 供前端调用，返回学习状态
     */
    public function studyStatusAry(){
        $list = array_values($this->studyStatusMap());
        if (!empty($list)) {
            $this->success('查询成功', $list);
        }
        $this->error('暂无数据');
    }

    /**
     * 订单整理
     */
    public function collation(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            $videoId = $param['video_id'] ?? 0;
            if(empty($videoId)){
                $this->error('在线课程ID必须');
            }

            //获取课程详情
            $info = $this->onlineVideoLogic->getInfo($param['shop_id'],$videoId);
            if(empty($info)){
                $this->error('课程不存在');
            }

            //验证该课程是否已支付
            $orderInfo = $this->onlineVideoOrderLogic->getOrderInfoByVideoId($param['shop_id'],$videoId);
            if(!empty($orderInfo)){
                if($orderInfo['status'] == 1){
                    $this->error('该课程存在未支付订单，请先支付或关闭订单后再下单');
                }else if($orderInfo['status'] == 2){
                    $this->error('该课程已支付，无需重复下单');
                }
            }

            //验证用户是否允许下单
            $checkRes = $this->onlineVideoOrderLogic->checkCreateOrder($videoId,$param['user_id']);
            if(!$checkRes){
                $this->error('该用户无法报名该课程');
            }

            //todo 未实现用户信息接口，默认空数组
            $userInfo = [];
            $info['user_info'] = $userInfo;

            if(!empty($info)){
                $this->success('查询成功',$info);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 创建订单
     */
    public function create(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            $videoId = $param['video_id'] ?? 0;
            if(empty($videoId)){
                $this->error('在线课程ID必须');
            }

            if(!isset($param['pay_type']) || !isset($this->payTypeMap()[$param['pay_type']])){
                $this->error('支付方式不可用');
            }

            if(!isset($param['receive_mobile']) || empty($param['receive_mobile'])){
                $this->error('手机号码不能为空');
            }

            //获取课程详情
            $info = $this->onlineVideoLogic->getInfo($param['shop_id'],$videoId);
            if(empty($info)){
                $this->error('课程不存在');
            }

            //验证用户是否允许下单
            $checkRes = $this->onlineVideoOrderLogic->checkCreateOrder($videoId,$param['user_id']);
            if(!$checkRes){
                $this->error('该用户无法报名该课程');
            }

            Db::startTrans();
            try {
                $orderInfo = [
                    'out_trade_no' => date("YmdHis") . mt_rand(100000, 999999),
                    'shop_id' => $param['shop_id'],
                    'user_id' => $param['user_id'],
                    'receive_mobile' => $param['receive_mobile'] ?? '',
                    'video_id' => $videoId,
                    'status' => 1,
                    'price' => $info['price'] ?? 0,
                    'pay_type' => $param['pay_type'],
                    'createtime' => time()
                ];

                $orderId = OnlineVideoOrderModel::insertGetId($orderInfo);

                //创建主订单记录
                $this->payLogic->createOrder([
                    'shop_id' => $param['shop_id'],
                    'controller' => 'online/video_order',
                    'order_sn' => $orderInfo['out_trade_no'],
                    'order_id' => $orderId,
                    'user_id' => $param['user_id'],
                    'price' => $orderInfo['price'],
                    'pay_type' => $param['pay_type'] == 1 ? 'wechat' : ($param['pay_type'] == 2 ? 'alipay' : ''),
                    'real_price' => $orderInfo['price'],
                    'pay_amount' => $orderInfo['price'],
                    'status' => 0,
                    'createtime' => time()
                ]);

                //如果课程价格为0，则直接支付成功
                $payStatus = 1; //待支付
                if($info['price'] == 0){
                    //执行支付成功回调
                    $res = $this->onlineVideoOrderLogic->payment(
                        [
                            'out_trade_no' => $orderInfo['out_trade_no']
                        ]
                    );
                    if($res){
                        $payStatus = 2; //已支付
                    }
                }

                Db::commit();
                $this->success('下单成功',['order_id' => $orderId,'pay_status' => $payStatus]);
            }catch (Exception $e){
                Db::rollback();
                $this->error('下单失败');
            }
        }
        $this->error('请求错误');
    }

    /**
     * 微信支付回调
     * todo 需按实际情况修改
     */
    public function notify(){
        //todo 默认写法，需按实际情况修改
        $xmlInfo = file_get_contents("php://input");
        //xms转数组
        $notifyRes = $this->xmlToArray($xmlInfo);

        //todo 回调数据验签成功
        if(true){
            $res = $this->onlineVideoOrderLogic->payment($notifyRes);
            if($res){
                echo 'success';
                exit;
            }
        }
        echo 'fail';
    }

    /**
     * 主订单支付回调,用于订单商品价格为0直接支付
     */
    public function pay_result(){
        $params = $this->request->param();

        $orderId = $params['order_id'] ?? 0;
        if(empty($orderId)){
            return false;
        }

        return $this->onlineVideoOrderLogic->payLogNotify($orderId);
    }

    /**
     * 获取订单详情
     */
    public function getInfo(){
        if($this->request->isPost()){
            $params = $this->request->param();

            //订单ID
            $orderId = $params['order_id'] ?? 0;
            if(!$orderId){
                $this->error('订单ID必须');
            }

            $info = $this->onlineVideoOrderLogic->getInfo($orderId);

            if(!empty($info)){
                $this->success('查询成功',$info);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 在线课程订单列表
     */
    public function orderList(){
        if($this->request->isPost()){
            $params = $this->request->param();
            //验证数据
            $params = $this->verifyData($params);

            $query = OnlineVideoOrderModel::where('user_id',$params['user_id'])
                ->where('status',2);
            //根据学习状态筛选
            if(isset($params['study_status'])){
                $query = $query->where('study_status',$params['study_status']);
            }

            $list = $query->field('id,shop_id,user_id,video_id,study_status')
                ->with([
                    'videoInfo' => function ($query) {
                        $query->with([
                                'videoTypeInfo' => function ($query) {
                                    $query->withField('id,name');
                                }
                            ])->withField('id,title,image,price,type_id');
                    }
                ])->order('createtime','desc')
                ->paginate(PAGE_SIZE);
            $list = objToArray($list) ?? [];

            if(!empty($list)){
                foreach ($list['data'] as $key => $val){
                    //获取总章节数
                    $subLevelIds = OnlineVideoSublevelModel::where('video_id',$val['video_info']['id'])
                        ->column('id');
                    $list['data'][$key]['video_info']['total_sublevel_count'] = !empty($subLevelIds) ? count($subLevelIds) : 0;

                    //获取学习中或已学习章节数
                    $list['data'][$key]['video_info']['already_study_count'] = OnlineVideoSublevelLogModel::where('video_id',$val['video_info']['id'])
                        ->whereIn('video_sublevel_id',$subLevelIds)
                        ->whereIn('status',[1,2])
                        ->count();
                }
                $this->success('查询成功',$list);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }
}
